package com.litt.saap.system.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.Resource;

import net.vidageek.mirror.dsl.Mirror;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.litt.core.common.BeanManager;
import com.litt.core.common.Utility;
import com.litt.core.dao.page.IPageList;
import com.litt.core.dao.ql.PageParam;
import com.litt.saap.core.module.tenant.config.TenantMetaConfigManager;
import com.litt.saap.core.module.tenant.config.meta.TenantMetaAttr;
import com.litt.saap.core.module.tenant.config.meta.TenantMetaAttrGroup;
import com.litt.saap.core.web.util.LoginUtils;
import com.litt.saap.system.dao.TenantConfigDao;
import com.litt.saap.system.dao.TenantDao;
import com.litt.saap.system.po.Tenant;
import com.litt.saap.system.po.TenantConfig;
import com.litt.saap.system.service.ITenantConfigService;
import com.litt.saap.system.vo.TenantConfVo;

/**
 * 
 * Tenant config service interface.
 * <pre><b>Description：</b>
 *    Tenant config Management
 * </pre>
 * 
 * @author <a href="mailto:littcai@hotmail.com">Bob.cai</a>
 * @since 2015-02-09
 * @version 1.0
 */
public class TenantConfigServiceImpl implements ITenantConfigService{

	/** Logger. */
  private static final Logger logger = LoggerFactory.getLogger(TenantConfigServiceImpl.class);
    
  @Resource
  private TenantConfigDao tenantConfigDao;
  @Resource
  private TenantDao tenantDao;
    
  /**
	 * 初始化
	 */
  @Override
	public Map<Integer, TenantConfVo> init(){
		//一次性读取所有属性值（性能最好），并转换为两层Map，便于检索
		List<TenantConfig> tenantConfigList = tenantConfigDao.listAll();		
		Map<Integer, Map<String, TenantConfig>> allTenantConfigMap = new HashMap<Integer, Map<String,TenantConfig>>();
		for (TenantConfig tenantConfig : tenantConfigList)
    {
		  Map<String, TenantConfig> tenantConfigMap = allTenantConfigMap.get(tenantConfig.getTenantId());
		  if(tenantConfigMap==null)
		  {
		    tenantConfigMap = new HashMap<String, TenantConfig>();
		    tenantConfigMap.put(tenantConfig.getAttrKey(), tenantConfig);
		    allTenantConfigMap.put(tenantConfig.getTenantId(), tenantConfigMap);
		  }
		  else {
		    tenantConfigMap.put(tenantConfig.getAttrKey(), tenantConfig);
      }
    }
		//读取元数据
		TenantMetaAttrGroup[] attrGroups = TenantMetaConfigManager.getInstance().getAllTenantMetaAttrGroup();		
		
	 
	  //获得所有租户，并为每个租户创建一个配置对象，并缓存
	  List<Tenant> tenantList = tenantDao.listAll();
	  Map<Integer, TenantConfVo> tenantConfMap = new HashMap<Integer, TenantConfVo>(tenantList.size());
	  /** 租户配置全局缓存. */
	  Map<Integer, TenantConfVo> tenantConfMapCache = TenantMetaConfigManager.getInstance().getTenantConfCache();
		for (Tenant tenant : tenantList)
    {
		  TenantConfVo tenantConf = new TenantConfVo(tenant.getId());
		  
		  Map<String, TenantConfig> tenantConfigMap = allTenantConfigMap.get(tenant.getId());
		  if(tenantConfigMap!=null)
		  {
		    //编辑Meta，获得Key
		    for (TenantMetaAttrGroup attrGroup : attrGroups)
		    {
		      String code = attrGroup.getCode();
		      TenantMetaAttr[] attrs = attrGroup.getAttrList();
		      for (TenantMetaAttr attr : attrs)
          {
            String attrKey = code + "." + attr.getKey();
            TenantConfig tenantConfig = tenantConfigMap.get(attrKey); //从数据库获取配置值
            if(tenantConfig==null)
              continue;
            
            String value = tenantConfig.getAttrValue();
            Object objValue = value;
            if("int".equals(attr.getDataType()))
            {
              objValue = Utility.parseInt(value);
            }
            else if("boolean".equals(attr.getDataType()))
            {
              objValue = Utility.parseBoolean(value);
            }
            Object groupInstance = new Mirror().on(tenantConf).get().field(code);
            new Mirror().on(groupInstance).set().field(attr.getKey()).withValue(objValue);
            
          }
		    }
		  }
		  tenantConfMap.put(tenant.getId(), tenantConf);
    }	
		//全局缓存
		tenantConfMapCache.putAll(tenantConfMap);
		return tenantConfMapCache;
	}
	
	
	@Override
	public Integer save(TenantConfig tenantConfig) {
		return tenantConfigDao.save(tenantConfig);
	}

	
	@Override
	public void update(TenantConfig tenantConfig) {
		tenantConfigDao.update(tenantConfig);
	}

	
	@Override
	public void delete(Integer id) {
		tenantConfigDao.delete(id);
	}

	
	@Override
	public void delete(TenantConfig tenantConfig) {
		tenantConfigDao.delete(tenantConfig);
	}

	
	@Override
	public void deleteBatch(Integer[] ids) {
		if(ids!=null)
		{
			for (Integer id : ids) {
				this.delete(id);
			}
		}
	}

	
	@Override
	public TenantConfig load(Integer id) {
		
		TenantConfig tenantConfig = tenantConfigDao.load(id);
		//校验租户权限
		LoginUtils.validateTenant(tenantConfig.getTenantId());
	
		return tenantConfig;
	}

	
	@Override
	public IPageList listPage(PageParam pageParam) {
		
		String listHql = "select obj from TenantConfig obj "
				       + "-- and obj.tenantId={tenantId}";	
		
		return tenantConfigDao.listPage(listHql, pageParam);
	}


	@Override
	public void deleteByTenantId(Integer tenantId) {
		tenantConfigDao.deleteByTenantId(tenantId);
	}

	/**
	 * Update batch.
	 *
	 * @param tenantId the tenant id
	 * @param metaAttrGroups the meta attr groups
	 * @param paramMap the param map
	 */
	public void updateBatch(int tenantId, TenantMetaAttrGroup[] metaAttrGroups, Map<String, String> paramMap) 
	{
	  /** 租户配置全局缓存. */
	  Map<Integer, TenantConfVo> tenantConfCache = TenantMetaConfigManager.getInstance().getTenantConfCache();
    TenantConfVo tenantConf = tenantConfCache.get(tenantId);
	  
    List<TenantConfig> configList = tenantConfigDao.listByTenant(tenantId);
    Map<String, TenantConfig> dataMap = new HashMap<String, TenantConfig>();
    //检查数据库参数是否存在，不存在则删除
    for (TenantConfig tenantConfig : configList)
    {
//      if(!paramMap.containsKey(tenantConfig.getAttrKey()))
//      {
//        tenantConfigDao.delete(tenantConfig);
//        
//      }
      
      dataMap.put(tenantConfig.getAttrKey(), tenantConfig);
    }
    //更新数据
    for (TenantMetaAttrGroup attrGroup : metaAttrGroups)
    {
      String code = attrGroup.getCode();
      TenantMetaAttr[] attrs = attrGroup.getAttrList();
      for (TenantMetaAttr attr : attrs)
      {
        String attrKey = code+"."+attr.getKey();
        TenantConfig tenantConfig = dataMap.get(attrKey);
        if(tenantConfig!=null)  //存在，需要更新
        {
          tenantConfig.setAttrValue(paramMap.get(attrKey));
        }
        else 
        {
          tenantConfig = new TenantConfig(tenantId, attrKey, paramMap.get(attrKey));
          tenantConfigDao.save(tenantConfig);
        }
        //更新缓存
        String value = tenantConfig.getAttrValue();
        Object objValue = value;
        if("int".equals(attr.getDataType()))
        {
          objValue = Utility.parseInt(value);
        }
        else if("boolean".equals(attr.getDataType()))
        {
          objValue = Utility.parseBoolean(value);
        }
        Object groupInstance = new Mirror().on(tenantConf).get().field(code);
        new Mirror().on(groupInstance).set().field(attr.getKey()).withValue(objValue);
      }
    } 
    
    
        
  }

}
